package com.xingkeduo.pojo.utils;

import org.apache.commons.lang.time.DateFormatUtils;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Locale;

/**
 * 
 * @ClassName: DateUtils
 * @Description: 日期工具类, 继承org.apache.commons.lang.time.DateUtils类
 * @author lixin
 * @date 2018年9月21日 下午12:34:48
 *
 */
public class DateUtils extends org.apache.commons.lang.time.DateUtils {

	private static String[] parsePatterns = { "yyyy-MM-dd", "yyyy-MM", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm",
			"yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm", "yyyyMMddHHmmss", "yyyy.MM.dd", "yyyy.MM","HH:mm","HH:mm:ss" };
	/**
	 * Default time format : yyyy-MM-dd HH:mm:ss
	 */
	public static final String DEFAULT_DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";

	public static final String EN_DATE_TIME_FORMAT = "yyyyMMddHHmmss";

	public static final String EN_DATE_FORMAT = "yyyy-MM-dd HH:mm";

	public static final String TIME_SECOND_FORMAT = "HH:mm:ss";

	public static final String TIME_SECOND_FORMAT_EN = "HHmmss";

	public static final String DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm";

	public static final String TIME_FORMAT = "HH:mm";

	public static final String UTC_FORMAT = "yyyy-MM-dd'T'HH:mm:ss'Z'";

	public static final String DATE_FORMAT = "yyyy-MM-dd";

	public static final String DATE_FORMAT_V2 = "yyyy.MM.dd";

	public static final String DATE_FORMAT_EN = "yyyyMMdd";

	public static final String DATE_FORMAT_CN = "yyyy年MM月dd日";

	public static final String DATE_TIME_FORMAT_CN = "yyyy年MM月dd日 HH:mm";

	public static final String MONTH_FORMAT_CN = "MM月dd日";

	public static final String MONTH_FORMAT = "yyyy-MM";

	public static final String MONTH_FORMAT_EN = "yyyyMM";

	public static final String DAY_FORMAT = "dd";

	public static final String YEAR_FORMAT = "yyyy";

	public static final String DATE_FORMAT_V3 = "yyyy/MM/dd";
	
	public static String getDate() {
		return getDate(DATE_FORMAT);
	}

	/**
	 * 得到当前日期字符串 格式（yyyy-MM-dd） pattern可以为："yyyy-MM-dd" "HH:mm:ss" "E"
	 */
	public static String getDate(String pattern) {
		return DateFormatUtils.format(new Date(), pattern);
	}

	/**
	 * 得到日期字符串 默认格式（yyyy-MM-dd） pattern可以为："yyyy-MM-dd" "HH:mm:ss" "E"
	 */
	public static String formatDate(Date date, Object... pattern) {
		String formatDate = null;
		if (date == null) {
			return formatDate;
		}
		if (pattern != null && pattern.length > 0) {
			formatDate = DateFormatUtils.format(date, pattern[0].toString());
		} else {
			formatDate = DateFormatUtils.format(date, DEFAULT_DATE_TIME_FORMAT);
		}
		return formatDate;
	}

	/**
	 * 得到当前时间字符串 格式（HH:mm:ss）
	 */
	public static String getTime() {
		return formatDate(new Date(), TIME_SECOND_FORMAT);
	}

	/**
	 * 得到当前日
	 */
	public static Date getCurdate() {
		return getCurdate(new Date());
	}

	public static Date getCurdate(Date date) {
		if(date==null) {
			date = new Date();
		}
		String dateStr = formatDate(date, DATE_FORMAT);
		return parseDate(dateStr);
	}
	/**
	 * 得到当前日期和时间字符串 格式（yyyy-MM-dd HH:mm:ss）
	 */
	public static String getDateTime() {
		return formatDate(new Date(), DEFAULT_DATE_TIME_FORMAT);
	}

	/**
	 * 得到当前年份字符串 格式（yyyy）
	 */
	public static String getYear() {
		return formatDate(new Date(), "yyyy");
	}

	/**
	 * 得到当前月份字符串 格式（MM）
	 */
	public static String getMonth() {
		return formatDate(new Date(), "MM");
	}

	/**
	 * 得到当天字符串 格式（dd）
	 */
	public static String getDay() {
		return formatDate(new Date(), "dd");
	}

	/**
	 * 得到当前星期字符串 格式（E）星期几
	 */
	public static String getWeek() {
		return formatDate(new Date(), "E");
	}

	/**
	 * 得到当前时间字符串
	 */
	public static String getHour() {
		return formatDate(new Date(), "HH");
	}
	/**
	 * 得到当前时间字符串
	 */
	public static String getHour(Date date) {
		return formatDate(date, "HH");
	}
	/**
	 * 日期型字符串转化为日期 格式 { "yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm",
	 * "yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm" }
	 */
	public static Date parseDate(Object str) {
		if (str == null) {
			return null;
		}
		try {
			return parseDate(str.toString(), parsePatterns);
		} catch (ParseException e) {
			return null;
		}
	}

	/**
	 * 获取过去的天数
	 * 
	 * @param date
	 * @return
	 */
	public static long pastDays(Date date) {
		long t = new Date().getTime() - date.getTime();
		return t / (24 * 60 * 60 * 1000);
	}

	/**
	 * 根据给定的日期来设置这一天的起始时间
	 * 
	 * @param date
	 * @return
	 */
	public static Date getBeginDate(Date date) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		c.set(Calendar.HOUR_OF_DAY, 0);
		c.set(Calendar.MINUTE, 0);
		c.set(Calendar.SECOND, 0);
		c.set(Calendar.MILLISECOND, 0);
		return c.getTime();
	}

	/**
	 * 根据给定的日期来设置这一天的结束时间
	 * 
	 * @param date
	 * @return
	 */
	public static Date getEndDate(Date date) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		c.set(Calendar.HOUR_OF_DAY, 23);
		c.set(Calendar.MINUTE, 59);
		c.set(Calendar.SECOND, 59);
		c.set(Calendar.MILLISECOND, 999);
		return c.getTime();
	}

	/**
	 * 获取给定日期的前几天或后几天
	 * 
	 * @param date
	 * @param days 为正则相加，为负则相减
	 * @return
	 */
	public static Date addSomeDays(Date date, int days) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.add(Calendar.DAY_OF_MONTH, days);
		return new Date(calendar.getTime().getTime());
	}

	/**
	 * 获取给定日期的前几月或后几月
	 * 
	 * @param date
	 * @param months 为正则相加，为负则相减
	 * @return
	 */
	public static Date addSomeMonths(Date date, int months) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.add(Calendar.MONTH, months);
		return new Date(calendar.getTime().getTime());
	}

	/**
	 * 获取某一个月共有多少天
	 * 
	 * @param year
	 * @param month 范围为 0-11
	 * @return
	 */
	public static int getDaysOfMonth(int year, int month) {
		return new GregorianCalendar(year, month, 1).getActualMaximum(Calendar.DAY_OF_MONTH);
	}

	/**
	 * 获取当前月共有多少天
	 * 
	 * @param year
	 * @param month 范围为 0-11
	 * @return
	 */
	public static int getDaysOfMonth(Date date) {
		int year = getYear(date);
		int month = getMonth(date);
		return getDaysOfMonth(year, month);
	}

	/**
	 * 根据年、月、日构造 date
	 * 
	 * @param year
	 * @param month month 的范围为 0-11
	 * @param day
	 * @return
	 */
	public static Date getDate(int year, int month, int day) {
		Calendar c = Calendar.getInstance();
		c.set(year, month, day);
		return c.getTime();
	}

	public static int getYear(Date date) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		return cal.get(Calendar.YEAR);
	}

	public static int getMonth(Date date) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		return cal.get(Calendar.MONTH);
	}

	public static int getDay(Date date) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		return cal.get(Calendar.DAY_OF_MONTH);
	}

	/**
	 * 计算两个日期之间相差的天数
	 * 
	 * @param smdate 较小的时间
	 * @param bdate  较大的时间
	 * @return 相差天数
	 * @throws ParseException
	 */
	public static int daysBetween(Date smdate, Date bdate) throws ParseException {
		SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT);
		smdate = sdf.parse(sdf.format(smdate));
		bdate = sdf.parse(sdf.format(bdate));
		Calendar cal = Calendar.getInstance();
		cal.setTime(smdate);
		long time1 = cal.getTimeInMillis();
		cal.setTime(bdate);
		long time2 = cal.getTimeInMillis();
		long between_days = (time2 - time1) / (1000 * 3600 * 24);

		return Integer.parseInt(String.valueOf(between_days));
	}

	/**
	 * 计算两个日期之间相差的月数
	 * 
	 * @param smdate 较小的时间
	 * @param bdate  较大的时间
	 * @return 相差天数
	 * @throws ParseException
	 */
	public static int monthBetween(Date smdate, Date bdate) throws ParseException {
		int result = 0;
		SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT);
		smdate = sdf.parse(sdf.format(smdate));
		bdate = sdf.parse(sdf.format(bdate));

		Calendar c1 = Calendar.getInstance();
		Calendar c2 = Calendar.getInstance();
		c1.setTime(smdate);
		c2.setTime(bdate);

		result = c2.get(Calendar.MONTH) - c1.get(Calendar.MONTH);

		return result == 0 ? 1 : Math.abs(result);
	}
	public static int getDayofweek() {
		return getDayofweek(new Date());
	}
	/**
	 * 
	* @Title: getDayofweek 
	* @Description: 获取当天是周几 
	* @param @param date
	* @param @return    设定文件 
	* @return int    返回类型 
	* @throws 
	* @author lixin
	* @date May 6, 2019 11:27:57 AM
	 */
	public static int getDayofweek(Date date) {
		Calendar cal = Calendar.getInstance();
		if (date==null) {
			cal.setTime(new Date(System.currentTimeMillis()));
		} else {
			cal.setTime(getCurdate(date));
		}
		int week = cal.get(Calendar.DAY_OF_WEEK)-1;
		return week == 0 ? 7: week;
	}

	/**
	 * 计算两个日期之间相差的年
	 * 
	 * @param smdate 较小的时间
	 * @param bdate  较大的时间
	 * @return 相差年数
	 * @throws ParseException
	 */
	public static int yearBetween(Date smdate, Date bdate) throws ParseException {
		SimpleDateFormat sdf = new SimpleDateFormat(YEAR_FORMAT);
		smdate = sdf.parse(sdf.format(smdate));
		bdate = sdf.parse(sdf.format(bdate));

		Calendar calBegin = Calendar.getInstance(); // 获取日历实例
		Calendar calEnd = Calendar.getInstance();
		calBegin.setTime(smdate); // 字符串按照指定格式转化为日期
		calEnd.setTime(bdate);
		return calEnd.get(Calendar.YEAR) - calBegin.get(Calendar.YEAR);
	}

	public static boolean isSameDay(Date date1, Date date2) {
		if (date1 == null || date2 == null) {
			return false;
		}
		String strDate1 = DateFormatUtils.format(new Date(date1.getTime()), DATE_FORMAT);
		String strDate2 = DateFormatUtils.format(new Date(date2.getTime()), DATE_FORMAT);
		return strDate1.equals(strDate2);
	}

	public static String getStrDate(Date date) {
		if (date == null) {
			return "";
		}
		return DateFormatUtils.format(new Date(date.getTime()), DATE_FORMAT);
	}

	/**
	 * formate to yyyy-MM-dd Date
	 * 
	 * @param dateText
	 * @return
	 */
	public static Date dateStrToDate(String dateText) {
		return dateStrToDate(dateText, DATE_FORMAT);
	}

	/**
	 * formate to pattern Date
	 * 
	 * @param dateText
	 * @param pattern
	 * @return
	 */
	public static Date dateStrToDate(String dateText, String pattern) {
		DateFormat dateFormat = createDateFormat(pattern);
		try {
			return dateFormat.parse(dateText);
		} catch (ParseException e) {
			throw new IllegalStateException("Parse date from [" + dateText + "," + pattern + "] failed", e);
		}
	}

	/**
	 * DateFormat
	 * 
	 * @param pattern
	 * @return
	 */
	private static DateFormat createDateFormat(String pattern) {
		return new SimpleDateFormat(pattern, Locale.SIMPLIFIED_CHINESE);
	}

	static int[] DAYS = { 0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };

	/**
	 * @param date yyyyMMddHHmmss
	 * @return
	 */
	public static boolean isValidDate(String date) {
		try {
			int year = Integer.parseInt(date.substring(0, 4));
			if (year <= 0)
				return false;
			int month = Integer.parseInt(date.substring(4, 6));
			if (month <= 0 || month > 12)
				return false;
			int day = Integer.parseInt(date.substring(6, 8));
			if (day <= 0 || day > DAYS[month])
				return false;
			if (month == 2 && day == 29 && !isGregorianLeapYear(year)) {
				return false;
			}
			int hour = Integer.parseInt(date.substring(8, 10));
			if (hour < 0 || hour > 23)
				return false;
			int minute = Integer.parseInt(date.substring(10, 12));
			if (minute < 0 || minute > 59)
				return false;
			int second = Integer.parseInt(date.substring(12, 14));
			if (second < 0 || second > 59)
				return false;

		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
		return true;
	}

	public static final boolean isGregorianLeapYear(int year) {
		return year % 4 == 0 && (year % 100 != 0 || year % 400 == 0);
	}

	public static Date addMinute(Date date, int minutes) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		cal.add(Calendar.MINUTE, minutes);
		return cal.getTime();
	}
	
	public static void main(String[] args) {
		Date date = parseDate("21:11");
		System.out.println(getHour(date));
	}
}
